// crt.cpp
//
// Keyboard Reader - emulate a hardware interrupt
// read the keyboard and signal the parent process when a key is received
//
//+++++++++++++++++++++++
// modifed to use the POSIX-style of obtaining shared memory
// by P. Dasiewicz, June 5, 2007
//+++++++++++++++++++++++++

#include <stdio.h>
#include <signal.h>
#include "global.h"
#include <fcntl.h>

#include <sys/mman.h>
#include <sys/wait.h>


int bufsize = BUFFERSIZE;
inputbuf * out_mem_p;


/*
int buf_index;
inputbuf * out_mem_p;*/

// do any necessary cleanup before exitting
// ( in this case, there is no cleanup to do)
// Basically, we rely on the parent process to cleanup shared memory
void in_die(int signal)
{
	exit(0);
}

int main (int argc, char * argv[])
{
    printf("\n CRT created\n");   
	int parent_pid, fid;
    inputbuf command;
	void * mmap_ptr;
	//inputbuf * out_mem_p;
	char c;


	// if parent tells us to terminate, then clean up first
	sigset(SIGINT,in_die);
    
	// get id of process to signal when we have input
	// and the file id of the memory mapped file
	// i.e. process input arguments 
	sscanf(argv[1], "%d", &parent_pid );
	sscanf(argv[2], "%d", &fid );  // get the file id

	// attach to shared memory so we can pass input to 
	// keyboard interrupt handler
	
	mmap_ptr = mmap((void*) 0,   /* Memory Location, 0 lets O/S choose */
		    bufsize,/* How many bytes to mmap */
		    PROT_READ | PROT_WRITE, /* Read and write permissions */
		    MAP_SHARED,    /* Accessible by another process */
		    fid,           /* which file is associated with mmap */
		    (off_t) 0);    /* Offset in page frame */
    if (mmap_ptr == MAP_FAILED){
      printf("Child memory map has failed, CRT is aborting!\n");
	  in_die(0);
    }
	out_mem_p = (inputbuf *) mmap_ptr; // now we have a shared memory pointer
    printf("\n crt mmap done\n");
    out_mem_p->ok_flag=0;
    while( out_mem_p->ok_flag == 0)
        usleep(100000);
	// copy input buffer
	//while(out_mem_p->indata[0] = '\0')
	 //   usleep(100000);
	if (out_mem_p->indata[0] != '\0')
	{
	    strcpy(command.indata,out_mem_p->indata); 

	    // we should parse the input string and execute the command given,
	    //  but for now we just echo the input
	    // 
	    printf("%s\n",command.indata);
	    //out_mem_p->ok_flag = 0;  // tell child that the buffer has been emptied
	    out_mem_p->ok_flag=1;
	}
   // kill(parent_pid,SIGUSR2);
    while(1);
    printf("\n crt has exited\n");
} // CRT
